<?php
/**
 * MySQL ConnectionFactory Class
 * Used for database abstraction to MySQL
 * @copyright 2008 Nicolas Schudel
 * @copyright Portions Copyright 2003-2006 Zen Cart Development Team
 * @copyright Portions Copyright 2003 osCommerce
 * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
 */

interface DatabaseConnection {
	public function connect($zf_host, $zf_user, $zf_password, $zf_database, $zf_pconnect = 'false', $zp_real = false);
	public function execute($sql);
	public function perform ($tableName, $tableData, $performType='INSERT', $performFilter='', $debug=false);
}

class ConnectionFactory implements DatabaseConnection {
	private $count_queries;
	private $total_query_time;
	private $db_connected;

	function __construct() {
		$this->count_queries = 0;
		$this->total_query_time = 0;
	}
	
	function __destruct() {
		$this->close();
	}

	private function notNull($value) {
		if (is_array($value) || is_object($value)) {
			if (sizeof($value) > 0) {
				return true;
			} else {
				return false;
			}
		} else {
			if (($value != '') && (strtolower($value) != 'null') && (strlen(trim($value)) > 0)) {
				return true;
			} else if (is_null($value)) {
				return false;
			}
		}
		return false;
	}
	
	private function set_error($zp_err_num, $zp_err_text, $zp_fatal = true) {
		$this->error_number = $zp_err_num;
		$this->error_text = $zp_err_text;
		if ($zp_fatal && $zp_err_num != 1141) {
			$this->show_error();
			die();
		}
	}
	
	function show_error() {
		$errormessage = $this->error_number . ' ' . $this->error_text;
		$errormessage .= 'in: ' . (strstr($this->zf_sql, 'db_cache') ? 'db_cache table' : $this->zf_sql);
		throw new Exception($errormessage);
	}
	
	public function hasService( $service ) {
		return false;
	}
	
	public function getQueryCount() {
		return $this->count_queries;
	}
	
	public function getQueryTime() {
		return $this->total_query_time;
	}
	
	public function insert_ID() {
		return @((is_null($___mysqli_res = mysqli_insert_id($this->link))) ? false : $___mysqli_res);
	}

	public function connect($zf_host, $zf_user, $zf_password, $zf_database, $zf_pconnect = 'false', $zp_real = false) {
		$this->database = $zf_database;
		$this->link = ((($GLOBALS["___mysqli_ston"] = mysqli_init()) && (mysqli_real_connect($GLOBALS["___mysqli_ston"], $zf_host,  $zf_user,  $zf_password, NULL, 3306, NULL,  $zp_real))) ? $GLOBALS["___mysqli_ston"] : FALSE);
		((bool)mysqli_query( $this->link, "USE $this->database"));
		$this->db_connected = true;
	  }

	function prepareInput($string) {
		return @((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $string) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
	}

	function close() {
		@((is_null($___mysqli_res = mysqli_close($this->link))) ? false : $___mysqli_res);
	}

	function execute($zf_sql, $zf_limit = false, $zf_cache = false, $zf_cachetime=0) {
		if ($zf_limit) $zf_sql = $zf_sql . ' LIMIT ' . $zf_limit;
		$this->zf_sql = $zf_sql;
		$time_start = explode(' ', microtime());
		$obj = new ConnectionFactoryResult;
		if (!$this->db_connected) $this->set_error('0', "Database not connected");
		$zp_db_resource = @mysqli_query( $this->link, $zf_sql);
		if (!$zp_db_resource) $this->set_error(@((is_object($this->link)) ? mysqli_errno($this->link) : (($___mysqli_res = mysqli_connect_errno()) ? $___mysqli_res : false)),@((is_object($this->link)) ? mysqli_error($this->link) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)));
		$obj->resource = $zp_db_resource;
		$obj->cursor = 0;
		if ($obj->recordCount() > 0) {
		$obj->EOF = false;
		$zp_result_array = @mysqli_fetch_array($zp_db_resource);
		if ($zp_result_array) {
			while (list($key, $value) = each($zp_result_array)) {
				if (!ereg('^[0-9]', $key)) {
					$obj->fields[$key] = $value;
				}
			}
			$obj->EOF = false;
		} else {
			$obj->EOF = true;
		}
		} else {
			$obj->EOF = true;
		}
		$time_end = explode (' ', microtime());
		$query_time = $time_end[1]+$time_end[0]-$time_start[1]-$time_start[0];
		$this->total_query_time += $query_time;
		$this->count_queries++;
		return($obj);
	}

	function perform($table, $data, $action = 'insert', $parameters = '', $link = 'db_link') {
		reset($data);
		if ($action == 'insert') {
			$query = 'insert into ' . $table . ' (';
			while (list($columns, ) = each($data)) {
				$query .= $columns . ', ';
			}
			$query = substr($query, 0, -2) . ') values (';
			reset($data);
			while (list(, $value) = each($data)) {
				switch ((string)$value) {
				case 'now()':
					$query .= 'now(), ';
				break;
				case 'null':
					$query .= 'null, ';
				break;
				default:
					$query .= '\'' . addslashes($value) . '\', ';
				break;
				}
			}
			$query = substr($query, 0, -2) . ')';
		} elseif ($action == 'update') {
			$query = 'update ' . $table . ' set ';
			while (list($columns, $value) = each($data)) {
				switch ((string)$value) {
				case 'now()':
					$query .= $columns . ' = now(), ';
				break;
				case 'null':
					$query .= $columns .= ' = null, ';
				break;
				default:
					$query .= $columns . ' = \'' . addslashes($value) . '\', ';
				break;
				}
			}
			$query = substr($query, 0, -2) . ' where ' . $parameters;
		}
		return $this->execute($query);
	}
}

class ConnectionFactoryResult {

	function __construct() {
		$this->is_cached = false;
	}
	
	function moveNext() {
		$this->cursor++;
		if ($this->is_cached) {
			if ($this->cursor >= sizeof($this->result)) {
				$this->EOF = true;
			} else {
				while(list($key, $value) = each($this->result[$this->cursor])) {
					$this->fields[$key] = $value;
				}
			}
		} else {
			$zp_result_array = @mysqli_fetch_array($this->resource);
			if (!$zp_result_array) {
				$this->EOF = true;
			} else {
				while (list($key, $value) = each($zp_result_array)) {
					if (!ereg('^[0-9]', $key)) {
						$this->fields[$key] = $value;
					}
				}
			}
		}
	}
	
	function moveNextRandom() {
		$this->cursor++;
		if ($this->cursor < $this->Limit) {
			$zp_result_array = $this->result[$this->result_random[$this->cursor]];
			while (list($key, $value) = each($zp_result_array)) {
				if (!ereg('^[0-9]', $key)) {
					$this->fields[$key] = $value;
				}
			}
		} else {
			$this->EOF = true;
		}
	}
	
	function recordCount() {
		return @mysqli_num_rows($this->resource);
	}
	
	function move($zp_row) {
		if (@mysqli_data_seek($this->resource,  $zp_row)) {
			$zp_result_array = @mysqli_fetch_array($this->resource);
			while (list($key, $value) = each($zp_result_array)) {
				$this->fields[$key] = $value;
			}
			@mysqli_data_seek($this->resource,  $zp_row);
			$this->EOF = false;
			return;
		} else {
			$this->EOF = true;
		}
	}
}
?>
